package com.darren.euc.service.impl;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.darren.euc.dao.ContractDao;
import com.darren.euc.dao.ContractHirePurchaseDao;
import com.darren.euc.dao.ContractProductDao;
import com.darren.euc.entity.Contract;
import com.darren.euc.entity.ContractHirePurchase;
import com.darren.euc.entity.ContractProduct;
import com.darren.euc.entity.PageBean;
import com.darren.euc.service.ContractService;
import com.darren.euc.util.StringUtil;

import net.sf.json.JSONObject;


@Service
public class ContractServiceImpl implements ContractService {
	
	private static final Logger log = Logger.getLogger(ContractServiceImpl.class);
	
	@Autowired
    private ContractDao contractDao;
	
	@Autowired
    private ContractProductDao contractProductDao;
	
	@Autowired
    private ContractHirePurchaseDao contractHirePurchaseDao;
		
    @Override
    public Contract save(Contract contract) {   	
    	
    	for(ContractProduct contractProduct:contract.getContractProductList()){
    		contractProductDao.save(contractProduct);
    	}
    	if(contract != null && "入驻合同".equals(contract.getContractType())){    		
    		Calendar calendar=Calendar.getInstance();
        	calendar.setTime(contract.getContractStartTime());
    		int contractYearStart = calendar.get(Calendar.YEAR);
    		int contractMonthStart = calendar.get(Calendar.MONTH);    		
    		calendar.setTime(contract.getContractEndTime());
    		int contractYearEnd = calendar.get(Calendar.YEAR);
    		int contractMonthEnd = calendar.get(Calendar.MONTH);    		
    		int months1 = (contractYearEnd - contractYearStart) * 12 ;//总月数
    		if(contractMonthEnd - contractMonthStart >= 0){
    			months1 += contractMonthEnd - contractMonthStart + 1;
    		}else{
    			months1 += contractMonthEnd - contractMonthStart + 1;
    		}        		
    		contract.setMonths(months1);
        	contract = contractDao.save(contract);
        	for(ContractProduct contractProduct:contract.getContractProductList()){
        		contractProduct.setContract(contract);
        		contractProduct.setCreateTime(contract.getCreateTime());
        		contractProduct.setCreateUserId(contract.getCreateUser().getId());
        		contractProduct.setLastModifyTime(contract.getLastModifyTime());
        		contractProduct.setLastModifyUserId(contract.getLastModifyUserId());
        		contractProductDao.update(contractProduct);
        	}
        	ContractHirePurchase depositAmount = new ContractHirePurchase();//押金
    		depositAmount.setHirePurchaseNumber(0);
    		depositAmount.setHirePurchaseStart(contract.getContractStartTime());
    		depositAmount.setHirePurchaseEnd(contract.getContractEndTime());
    		depositAmount.setBill_Date(contract.getPaymentFirstTime());
    		depositAmount.setHirePurchaseAmount(contract.getDepositAmount());
    		depositAmount.setRealPaymentAmount(0D);
    		depositAmount.setHirePurchaseStatus("未回款");
    		depositAmount.setContract(contract);
    		contractHirePurchaseDao.save(depositAmount);
    		contract.getContractHirePurchaseList().add(depositAmount);    		
    		
    		ContractHirePurchase firstPayment = new ContractHirePurchase();//第一期
    		firstPayment.setHirePurchaseNumber(1);
    		firstPayment.setHirePurchaseStart(contract.getContractStartTime());
    		
    		Calendar calendarFirst=Calendar.getInstance();
    		calendarFirst.setTime(contract.getPaymentFirstTime());
    		calendarFirst.set(Calendar.DAY_OF_MONTH, calendarFirst.getActualMaximum(Calendar.DAY_OF_MONTH));
    		firstPayment.setHirePurchaseEnd(calendarFirst.getTime());   
    		firstPayment.setBill_Date(contract.getPaymentFirstTime());
    		firstPayment.setHirePurchaseAmount(contract.getPaymentFirst());
    		firstPayment.setRealPaymentAmount(0D);
    		firstPayment.setHirePurchaseStatus("未回款");
    		firstPayment.setContract(contract);
    		//contractHirePurchaseDao.save(firstPayment);
    		//contract.getContractHirePurchaseList().add(firstPayment);
    		
    		if(contract.getPaymentCount() >= 1){
    			SimpleDateFormat formate = new SimpleDateFormat("yyyy-MM-dd");
    			Calendar contractCalendarStart=Calendar.getInstance();
        		Double remainAmount = contract.getContractAmount() -  contract.getPaymentFirst();
        		
        		contractCalendarStart.setTime(contract.getContractStartTime());
        		int yearStart = contractCalendarStart.get(Calendar.YEAR);
        		int monthStart = contractCalendarStart.get(Calendar.MONTH);
        		Calendar contractCalendarEnd=Calendar.getInstance();
        		contractCalendarEnd.setTime(contract.getContractEndTime());
        		int yearEnd = contractCalendarEnd.get(Calendar.YEAR);
        		int monthEnd = contractCalendarEnd.get(Calendar.MONTH);  
        		
        		int monthCount = (yearEnd - yearStart) * 12 ;//总月数
        		if(monthEnd - monthStart >= 0){
        			monthCount += monthEnd - monthStart + 1;
        		}else{
        			months1 = months1 + contractMonthEnd - contractMonthStart + 1;
        		}        		
        		contract.setMonths(monthCount);
        		int months = (monthCount /contract.getPaymentCount())-1;
        		
        		Double oneTimePayAmount = remainAmount / (contract.getPaymentCount() - 1); 
        		
        		
        		for(int i = 1; i <= contract.getPaymentCount(); i++){
        			contractCalendarStart.setTime(contract.getContractStartTime());
        			ContractHirePurchase contractHirePurchase = new ContractHirePurchase();//第i期
        			contractHirePurchase.setHirePurchaseNumber(i);    			
        			if(i != 1){
        				contractCalendarStart.add(Calendar.MONTH, months*(i-1));
        				contractCalendarStart.set(Calendar.DAY_OF_MONTH,1);//设置为帐单期为帐单月第一天开始
        			}
        			contractHirePurchase.setHirePurchaseStart(contractCalendarStart.getTime());
        			
        			
        			Calendar billDate = Calendar.getInstance();
        			billDate.setTime(contractCalendarStart.getTime());
        			billDate.set(Calendar.DAY_OF_MONTH, billDate.getActualMaximum(Calendar.DAY_OF_MONTH));         			
        			if(i != 1){
        				contractHirePurchase.setBill_Date(contractCalendarStart.getTime());	
        			}else{
        				contractHirePurchase.setBill_Date(contract.getPaymentFirstTime());
        			}
        			
        			Calendar hirePurchaseEnd = Calendar.getInstance();
        			hirePurchaseEnd.setTime(contract.getContractStartTime());
        			hirePurchaseEnd.add(Calendar.MONTH, months*(i-1));
        			hirePurchaseEnd.set(Calendar.DAY_OF_MONTH, hirePurchaseEnd.getActualMaximum(Calendar.DAY_OF_MONTH));
        			if( i == contract.getPaymentCount()){
        				contractHirePurchase.setHirePurchaseEnd(contract.getContractEndTime());
        			}else{
        				contractHirePurchase.setHirePurchaseEnd(hirePurchaseEnd.getTime());
        			}       			
        			
        			if(i != 1){
        				contractHirePurchase.setHirePurchaseAmount(oneTimePayAmount);
        			}else{
        				contractHirePurchase.setHirePurchaseAmount(contract.getPaymentFirst());
        			}
        			contractHirePurchase.setRealPaymentAmount(0D);
        			contractHirePurchase.setHirePurchaseStatus("未回款");
        			contractHirePurchase.setContract(contract);
            		contractHirePurchaseDao.save(contractHirePurchase);
            		contract.getContractHirePurchaseList().add(contractHirePurchase);
        		}    			
    		}    		
    	}else{    		
    		contract = contractDao.save(contract);
    	}    	
        return contract;
    }
    
    @Override
    public Contract update(Contract contract) {    	
    	if(contract != null){
    		contractProductDao.deleteByContractId(contract.getId());
    	}
    	for(ContractProduct contractProduct:contract.getContractProductList()){
    		contractProduct.setId(null);
    		contractProductDao.save(contractProduct);
    	} 
    	if(contract != null && "入驻合同".equals(contract.getContractType())){
    		Calendar calendar=Calendar.getInstance();
        	calendar.setTime(contract.getContractStartTime());
    		int contractYearStart = calendar.get(Calendar.YEAR);
    		int contractMonthStart = calendar.get(Calendar.MONTH);    		
    		calendar.setTime(contract.getContractEndTime());
    		int contractYearEnd = calendar.get(Calendar.YEAR);
    		int contractMonthEnd = calendar.get(Calendar.MONTH);    		
    		int months1 = (contractYearEnd - contractYearStart) * 12 ;//总月数
    		if(contractMonthEnd - contractMonthStart >= 0){
    			months1 += contractMonthEnd - contractMonthStart + 1;
    		}else{
    			months1 = months1 + contractMonthEnd - contractMonthStart + 1;//contractMonthEnd - contractMonthStart - 12;
    		}        		
    		contract.setMonths(months1);
        	contract = contractDao.update(contract);
        	for(ContractProduct contractProduct:contract.getContractProductList()){
        		contractProduct.setContract(contract);
        		contractProduct.setCreateTime(contract.getCreateTime());
        		contractProduct.setCreateUserId(contract.getCreateUser().getId());
        		contractProduct.setLastModifyTime(contract.getLastModifyTime());
        		contractProduct.setLastModifyUserId(contract.getLastModifyUserId());
        		contractProductDao.update(contractProduct);
        	}
        	for(ContractHirePurchase hirePurchase:contract.getContractHirePurchaseList()){
    			contractHirePurchaseDao.delete(hirePurchase);
    		}
    		contract.getContractHirePurchaseList().clear();
    		ContractHirePurchase depositAmount = new ContractHirePurchase();//押金
    		depositAmount.setHirePurchaseNumber(0);
    		depositAmount.setHirePurchaseStart(contract.getContractStartTime());
    		depositAmount.setHirePurchaseEnd(contract.getContractEndTime());
			depositAmount.setBill_Date(contract.getPaymentFirstTime());
    		depositAmount.setHirePurchaseAmount(contract.getDepositAmount());
    		depositAmount.setRealPaymentAmount(0D);
    		depositAmount.setHirePurchaseStatus("未回款");
    		depositAmount.setContract(contract);
    		contractHirePurchaseDao.save(depositAmount);
    		contract.getContractHirePurchaseList().add(depositAmount);    		
    		
    		ContractHirePurchase firstPayment = new ContractHirePurchase();//第一期
    		firstPayment.setHirePurchaseNumber(1);
    		firstPayment.setHirePurchaseStart(contract.getContractStartTime());
    		
    		Calendar calendarFirst=Calendar.getInstance();
    		calendarFirst.setTime(contract.getPaymentFirstTime());
    		calendarFirst.set(Calendar.DAY_OF_MONTH, calendarFirst.getActualMaximum(Calendar.DAY_OF_MONTH));
    		firstPayment.setHirePurchaseEnd(calendarFirst.getTime());
			firstPayment.setBill_Date(contract.getPaymentFirstTime());
    		firstPayment.setHirePurchaseAmount(contract.getPaymentFirst());
    		firstPayment.setRealPaymentAmount(0D);
    		firstPayment.setHirePurchaseStatus("未回款");
    		firstPayment.setContract(contract);
    		//contractHirePurchaseDao.save(firstPayment);
    		//contract.getContractHirePurchaseList().add(firstPayment);
    		
    		if(contract.getPaymentCount() >= 1){
    			SimpleDateFormat formate = new SimpleDateFormat("yyyy-MM-dd");
    			Calendar contractCalendarStart=Calendar.getInstance();
        		Double remainAmount = contract.getContractAmount() -  contract.getPaymentFirst();
        		contractCalendarStart.setTime(contract.getContractStartTime());
        		int yearStart = contractCalendarStart.get(Calendar.YEAR);
        		int monthStart = contractCalendarStart.get(Calendar.MONTH);    		
        		
        		Calendar contractCalendarEnd=Calendar.getInstance();
        		contractCalendarEnd.setTime(contract.getContractEndTime());
        		int yearEnd = contractCalendarEnd.get(Calendar.YEAR);
        		int monthEnd = contractCalendarEnd.get(Calendar.MONTH);    		
        		int monthCount = (yearEnd - yearStart) * 12 ;//总月数
        		if(monthEnd - monthStart >= 0){
        			monthCount += monthEnd - monthStart + 1;
        		}else{
        			monthCount += monthEnd - monthStart + 1;
        		}        		
        		contract.setMonths(monthCount);
        		int months = (monthCount /contract.getPaymentCount())-1;
        		Double oneTimePayAmount = remainAmount / (contract.getPaymentCount() - 1); 
        		
        		
        		for(int i = 1; i <= contract.getPaymentCount(); i++){
        			contractCalendarStart.setTime(contract.getContractStartTime());
        			ContractHirePurchase contractHirePurchase = new ContractHirePurchase();//第i期
        			contractHirePurchase.setHirePurchaseNumber(i); 
        			if(i != 1){
        				contractCalendarStart.add(Calendar.MONTH, months*(i-1));
        				contractCalendarStart.set(Calendar.DAY_OF_MONTH,1);//设置为帐单期为帐单月第一天开始
        			}        			
        			contractHirePurchase.setHirePurchaseStart(contractCalendarStart.getTime());        			
        			
        			Calendar billDate = Calendar.getInstance();
        			billDate.setTime(contractCalendarStart.getTime());
        			billDate.set(Calendar.DAY_OF_MONTH, billDate.getActualMaximum(Calendar.DAY_OF_MONTH));  
        			if(i != 1){
        				contractHirePurchase.setBill_Date(contractCalendarStart.getTime());	
        			}else{
        				contractHirePurchase.setBill_Date(contract.getPaymentFirstTime());
        			}
        			
        			Calendar hirePurchaseEnd = Calendar.getInstance();
        			hirePurchaseEnd.setTime(contract.getContractStartTime());
        			hirePurchaseEnd.add(Calendar.MONTH, months*i-1);
        			hirePurchaseEnd.set(Calendar.DAY_OF_MONTH, hirePurchaseEnd.getActualMaximum(Calendar.DAY_OF_MONTH)); 
        			if( i == contract.getPaymentCount()){
        				contractHirePurchase.setHirePurchaseEnd(contract.getContractEndTime());
        			}else{
        				contractHirePurchase.setHirePurchaseEnd(hirePurchaseEnd.getTime());
        			}       			
        			
        			if(i != 1){
        				contractHirePurchase.setHirePurchaseAmount(oneTimePayAmount);
        			}else{
        				contractHirePurchase.setHirePurchaseAmount(contract.getPaymentFirst());
        			}
        			contractHirePurchase.setRealPaymentAmount(0D);
        			contractHirePurchase.setHirePurchaseStatus("未回款");
        			contractHirePurchase.setContract(contract);
            		contractHirePurchaseDao.save(contractHirePurchase);
            		contract.getContractHirePurchaseList().add(contractHirePurchase);
        		}    			
    		}   
    	}
        return contractDao.update(contract);
    }
    
    @Override
    public Contract findById(Integer id) {
        return contractDao.findById(id);
    }

    @Override
    public void delete(Contract contract) {
    	contractDao.delete(contract);
    }
    
	@Override
	public List<Contract> getAll() {
		return contractDao.getAll();
	}
	
	
	@SuppressWarnings("rawtypes")
	public PageBean queryForPageUseHQL(JSONObject requestJson,Integer pageSize, Integer currentPage){		
		String HQL = null;
		String likes = null;
		String equals = null;
		List<Object> parameters = new ArrayList<Object>();
		JSONObject likeJson = requestJson.getJSONObject("like");
		Iterator likeIterator = likeJson.keys();
		while(likeIterator.hasNext()){
			String key = (String) likeIterator.next();
			key = StringUtil.convertNullToEmptyString(key);
			String value = likeJson.getString(key);
			value = StringUtil.convertNullToEmptyString(value);
			if(!"".equals(value)){
				likes = (likes == null?"": likes + " OR ") +  key + " like ? ";
				parameters.add("%"+value+"%");
			}
		}
		HQL = likes == null?null:(" (" + likes + ") ");		
		JSONObject equalsJson = requestJson.getJSONObject("equals");
        Iterator equalsIterator = equalsJson.keys();        
		while(equalsIterator.hasNext()){
			String key = (String) equalsIterator.next();
			key = StringUtil.convertNullToEmptyString(key);
			String value = equalsJson.getString(key);
			value = StringUtil.convertNullToEmptyString(value);
			if(!"".equals(value)){
				if("visitTimeStart".equals(key)){
					DateFormat format = new SimpleDateFormat("yyyy-MM-dd");  
					try {
						Date startDate = (Date)format.parse(value);
						parameters.add(startDate);
					} catch (ParseException e) {
						log.error(e.getMessage(),e);
					} 
					equals = (equals == null?"": ""+equals + " and ") +  " visitTime >= ? ";					
				}else if("visitTimeEnd".equals(key)){
					DateFormat format = new SimpleDateFormat("yyyy-MM-dd");  
					try {
						Date endDate = (Date)format.parse(value);
						Calendar calendar = Calendar.getInstance(); 
						calendar.setTime(endDate); 						
						int day=calendar.get(Calendar.DATE); 
						calendar.set(Calendar.DATE,day+1); 				
						parameters.add(calendar.getTime());
					} catch (ParseException e) {
						log.error(e.getMessage(),e);
					} 
					equals = (equals == null?"": ""+equals + " and ") +  " visitTime <= ? ";
					
				}else if("spaceId".equals(key)){
					equals = (equals == null?"": ""+equals + " and ") +  key + " = ? ";
					parameters.add(Integer.parseInt(value));
				}else if("enable".equals(key)){
					equals = (equals == null?"": ""+equals + " and ") +  key + " = ? ";
					parameters.add(Boolean.parseBoolean(value));
				}else{
					equals = (equals == null?"": ""+equals + " and ") +  key + " = ? ";
					parameters.add(value);
				}				
			}
		}		
		if(HQL != null){
			if(equals != null){
				HQL = HQL + " and " + equals;
			}
		}else{
			HQL = equals;
		}
		HQL = " from Contract " + (HQL == null?"":" where " + HQL) + " and enable = true";
		return contractDao.queryForPageByHQL(HQL, pageSize, currentPage,parameters.toArray());
	}

	
	@SuppressWarnings("rawtypes")
	public PageBean queryFinanceContracts(JSONObject requestJson,Integer pageSize, Integer currentPage){
		List<Object> parameters = new ArrayList<Object>();
		String SQL = " select  distinct contract.*  "
					+"	from euc_contracts contract   "
					+"	LEFT JOIN euc_orders orders on contract.order_id = orders.id  "
					+"	LEFT JOIN euc_client client on client.id = orders.client_id  "
					+"	where  1 = 1  ";		

		String clientName = requestJson.getString("clientName");
		if(clientName != null && !"".equals(clientName.trim())){
			SQL += " and (client.member_name like ? or client.company_name like ?) " ;
			parameters.add("%"+clientName+"%");
			parameters.add("%"+clientName+"%");
		}
		String spaceId = requestJson.getString("spaceId");
		if(spaceId != null && !"".equals(spaceId.trim())){
			SQL += " and orders.space_id = ? " ;
			parameters.add(Integer.parseInt(spaceId));
		}
		
		String contractType = requestJson.getString("contractType");
		if(contractType != null && !"".equals(contractType.trim())){
			SQL += " and contract.contract_type = ? " ;
			parameters.add(contractType);
		}
		
		String salesPerson = requestJson.getString("salesPerson");
		if(salesPerson != null && !"".equals(salesPerson.trim())){
			SQL += " and orders.sales_person_id = ? " ;
			parameters.add(Integer.parseInt(salesPerson));
		}
		
		String beginTime = requestJson.getString("beginTime");
		if(beginTime != null && !"".equals(beginTime.trim())){
			SQL += " and contract.create_time >= ? " ;
			parameters.add(beginTime + " 00:00:00");
		}
		
		String endTime = requestJson.getString("endTime");
		if(endTime != null && !"".equals(endTime.trim())){
			SQL += " and contract.create_time <= ? " ;
			parameters.add(endTime + " 23:59:59");
		}
		
		return contractDao.queryForPageBySQL(SQL, pageSize, currentPage,parameters.toArray());
	}
	
	
}